/**
 * 惠企政策抓取脚本
 * 用于抓取湖北省经信厅惠企政策信息并存入数据库
 */
const axios = require('axios');
const cheerio = require('cheerio');
const mysql = require('mysql2/promise');
const dotenv = require('dotenv');
const fs = require('fs').promises;
const path = require('path');

// 加载环境变量
dotenv.config({ path: '.env.local' });

// 数据库配置
const dbConfig = {
  host: process.env.DB_HOST || 'rm-bp14wd51i709c3z79ho.mysql.rds.aliyuncs.com',
  user: process.env.DB_USER || 'root',
  password: process.env.DB_PASSWORD || 'Ircnjfdhnvxwz@123',
  database: process.env.DB_NAME || 'xiaoyoubao',
  port: Number(process.env.DB_PORT) || 3306,
  waitForConnections: true,
  connectionLimit: 10,
};

// DeepSeek API 配置
const DEEPSEEK_API_KEY = process.env.DEEPSEEK_API_KEY || 'sk-dbc2528168b542acbf58df81f0c3db88';
const DEEPSEEK_API_URL = 'https://api.deepseek.com/v1/chat/completions';

// 目标网站配置
const BASE_URL = 'https://jxt.hubei.gov.cn';
const POLICY_LIST_URL = 'https://jxt.hubei.gov.cn/wzlm/hqzc/';

/**
 * 初始化数据库连接
 * @returns {Promise<import('mysql2/promise').Pool>}
 */
async function initDbConnection() {
  console.log('正在连接数据库...');
  try {
    const pool = mysql.createPool(dbConfig);
    const connection = await pool.getConnection();
    console.log('数据库连接成功');
    connection.release();
    return pool;
  } catch (error) {
    console.error('数据库连接失败:', error);
    throw error;
  }
}

/**
 * 抓取政策列表页
 * @param {number} page 页码
 * @returns {Promise<Array>} 政策列表
 */
async function crawlPolicyList(page = 1) {
  try {
    const url = `${POLICY_LIST_URL}${page > 1 ? `index_${page}.html` : ''}`;
    console.log(`正在抓取政策列表页: ${url}`);
    
    const response = await axios.get(url, {
      headers: {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
      }
    });
    
    const $ = cheerio.load(response.data);
    const policies = [];
    
    // 更新选择器匹配当前网站结构
    $('.list-b li').each((index, element) => {
      const titleElement = $(element).find('h4 a');
      const title = titleElement.text().trim();
      const link = titleElement.attr('href');
      
      if (!title || !link) return; // 跳过无效项
      
      // 有些链接可能是相对路径，需要处理成绝对路径
      const fullLink = link.startsWith('http') ? link : `${BASE_URL}${link.startsWith('/') ? '' : '/'}${link}`;
      
      // 提取日期和来源信息
      const infoText = $(element).find('.text').text().trim();
      const sourceMatch = infoText.match(/来源：([^\s]+)/);
      const source = sourceMatch ? sourceMatch[1].trim() : '湖北省经济和信息化厅';
      
      // 提取摘要内容
      const summary = $(element).find('.info').text().trim();
      
      policies.push({
        title,
        link: fullLink,
        source,
        summary,
        // 日期将在详情页中提取
      });
    });
    
    console.log(`成功获取 ${policies.length} 条政策信息`);
    return policies;
  } catch (error) {
    console.error(`抓取政策列表失败:`, error);
    return [];
  }
}

/**
 * 抓取政策详情
 * @param {string} url 政策详情URL
 * @returns {Promise<Object>} 政策详情
 */
async function crawlPolicyDetail(url) {
  try {
    console.log(`正在抓取政策详情: ${url}`);
    
    const response = await axios.get(url, {
      headers: {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
      }
    });
    
    const $ = cheerio.load(response.data);
    
    // 更新选择器匹配详情页结构
    // 标题
    const title = $('.view h2, .article-title').text().trim();
    
    // 发布信息
    const publishInfo = $('.view .info, .article-info').text().trim();
    const publishDate = publishInfo.match(/(\d{4}-\d{2}-\d{2})/)?.[1] || '';
    const source = publishInfo.match(/来源：([^\s]+)/)?.[1] || '湖北省经济和信息化厅';
    
    // 正文内容
    const content = $('.view .text, .article-content').html() || '';
    const plainContent = $('.view .text, .article-content').text().trim();
    
    return {
      title,
      publish_date: publishDate,
      source,
      content,
      plain_content: plainContent,
      original_url: url
    };
  } catch (error) {
    console.error(`抓取政策详情失败: ${url}`, error);
    return null;
  }
}

/**
 * 使用DeepSeek API生成政策摘要
 * @param {string} title 政策标题
 * @param {string} content 政策内容
 * @returns {Promise<Object>} 处理结果
 */
async function generatePolicySummary(title, content) {
  try {
    console.log(`正在使用DeepSeek生成政策摘要: ${title}`);
    
    // 限制内容长度，防止请求过大
    const truncatedContent = content.length > 8000 ? content.substring(0, 8000) + '...' : content;
    
    const prompt = `
你是一个专业的政策分析师，请帮我分析以下惠企政策，提取关键信息，并按照要求输出JSON格式结果。

政策标题: ${title}

政策内容:
${truncatedContent}

请提取以下信息:
1. 简短摘要（不超过150字）
2. 政策类别（从以下选项中选择最合适的一个：融资支持、税收优惠、产业发展、创新创业、人才支持、技术改造、其他政策）
3. 3-5个关键标签（从政策内容中提取最能代表该政策特点的关键词）
4. 政策要点（提取3-5条最重要的政策内容要点）
5. 申请条件（如有明确的申请条件，请提取出来）

请按照以下JSON格式返回结果：
{
  "summary": "政策摘要...",
  "category": "政策类别",
  "tags": ["标签1", "标签2", "标签3"],
  "keyPoints": ["要点1", "要点2", "要点3"],
  "requirements": ["条件1", "条件2", "条件3"]
}

注意:
- 仅返回JSON格式，不要包含其他说明文字
- 如果某项内容不存在，返回空数组或空字符串
`;

    const response = await axios.post(
      DEEPSEEK_API_URL,
      {
        model: 'deepseek-chat',
        messages: [
          { role: 'system', content: '你是一个专业的政策分析师，负责分析政府惠企政策并提取关键信息。' },
          { role: 'user', content: prompt }
        ],
        temperature: 0.3,
        max_tokens: 1500
      },
      {
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${DEEPSEEK_API_KEY}`
        }
      }
    );
    
    const result = response.data.choices[0].message.content;
    console.log('DeepSeek API返回结果:', result);
    
    // 提取JSON内容
    const jsonMatch = result.match(/\{[\s\S]*\}/);
    if (jsonMatch) {
      const jsonResult = JSON.parse(jsonMatch[0]);
      console.log('解析后的结果:', jsonResult);
      return jsonResult;
    } else {
      console.error('DeepSeek API返回结果解析失败');
      return {
        summary: `这是关于"${title}"的政策`,
        category: '其他政策',
        tags: ['政策', '湖北省'],
        keyPoints: ['请查看原文了解详情'],
        requirements: []
      };
    }
  } catch (error) {
    console.error('生成政策摘要失败:', error.response?.data || error.message);
    return {
      summary: `这是关于"${title}"的政策`,
      category: '其他政策',
      tags: ['政策', '湖北省'],
      keyPoints: ['请查看原文了解详情'],
      requirements: []
    };
  }
}

/**
 * 将政策保存到数据库
 * @param {import('mysql2/promise').Pool} pool 数据库连接池
 * @param {Object} policy 政策数据
 * @returns {Promise<number>} 插入的政策ID
 */
async function savePolicyToDatabase(pool, policy) {
  const connection = await pool.getConnection();
  try {
    // 开始事务
    await connection.beginTransaction();
    
    // 检查是否已存在相同URL的政策
    const [existingPolicies] = await connection.execute(
      'SELECT id FROM enterprise_policies WHERE original_url = ?',
      [policy.original_url]
    );
    
    // 处理空日期问题 - 使用当前日期作为默认值
    const publishDate = policy.publish_date ? policy.publish_date : new Date().toISOString().split('T')[0];
    
    let policyId;
    
    if (existingPolicies.length > 0) {
      // 更新已存在的政策
      policyId = existingPolicies[0].id;
      await connection.execute(
        `UPDATE enterprise_policies SET 
        title = ?, 
        summary = ?, 
        content = ?, 
        source = ?, 
        publish_date = ?, 
        category = ?, 
        tags = ?, 
        key_points = ?, 
        requirements = ?, 
        updated_at = CURRENT_TIMESTAMP 
        WHERE id = ?`,
        [
          policy.title,
          policy.summary,
          policy.content,
          policy.source,
          publishDate,
          policy.category,
          policy.tags.join(','),
          JSON.stringify(policy.keyPoints),
          JSON.stringify(policy.requirements),
          policyId
        ]
      );
      console.log(`更新政策: ${policy.title}`);
    } else {
      // 插入新政策
      const [result] = await connection.execute(
        `INSERT INTO enterprise_policies (
          title, summary, content, source, publish_date, original_url, category, tags, key_points, requirements
        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
        [
          policy.title,
          policy.summary,
          policy.content,
          policy.source,
          publishDate,
          policy.original_url,
          policy.category,
          policy.tags.join(','),
          JSON.stringify(policy.keyPoints),
          JSON.stringify(policy.requirements)
        ]
      );
      policyId = result.insertId;
      console.log(`插入新政策: ${policy.title}`);
    }
    
    // 记录爬取日志
    await connection.execute(
      'INSERT INTO enterprise_policy_crawl_logs (url, status, message) VALUES (?, ?, ?)',
      [policy.original_url, 'success', `成功抓取政策: ${policy.title}`]
    );
    
    // 提交事务
    await connection.commit();
    return policyId;
  } catch (error) {
    // 回滚事务
    await connection.rollback();
    console.error('保存政策失败:', error);
    
    // 记录失败日志
    try {
      await connection.execute(
        'INSERT INTO enterprise_policy_crawl_logs (url, status, message) VALUES (?, ?, ?)',
        [policy.original_url, 'failed', `保存失败: ${error.message}`]
      );
    } catch (logError) {
      console.error('记录失败日志出错:', logError);
    }
    
    throw error;
  } finally {
    connection.release();
  }
}

/**
 * 主函数
 */
async function main() {
  try {
    // 初始化数据库连接
    const pool = await initDbConnection();
    
    // 抓取多页政策列表，以获取更多内容
    let allPolicies = [];
    
    // 抓取前3页
    for (let page = 1; page <= 3; page++) {
      const pagePolicies = await crawlPolicyList(page);
      allPolicies = [...allPolicies, ...pagePolicies];
      
      // 如果当前页没有政策，则停止抓取
      if (pagePolicies.length === 0) break;
      
      // 避免频繁请求
      if (page < 3) await new Promise(resolve => setTimeout(resolve, 1000));
    }
    
    // 限制处理数量，避免API调用过多
    const MAX_POLICIES = 5;
    const limitedPolicies = allPolicies.slice(0, MAX_POLICIES);
    
    console.log(`将处理 ${limitedPolicies.length} 条政策`);
    
    // 处理每条政策
    for (const policyItem of limitedPolicies) {
      try {
        // 抓取政策详情
        const policyDetail = await crawlPolicyDetail(policyItem.link);
        
        if (!policyDetail) {
          console.error(`政策详情获取失败: ${policyItem.title}`);
          continue;
        }
        
        // 使用有效的标题
        const title = policyDetail.title || policyItem.title;
        
        // 使用DeepSeek API生成摘要
        const summary = await generatePolicySummary(title, policyDetail.plain_content);
        
        // 组装完整政策数据
        const fullPolicy = {
          title: title,
          summary: summary.summary || policyItem.summary, // 如果API返回为空，使用列表页摘要
          content: policyDetail.content,
          source: policyDetail.source,
          publish_date: policyDetail.publish_date,
          original_url: policyDetail.original_url,
          category: summary.category || '其他政策', // 确保有默认分类
          tags: summary.tags && summary.tags.length > 0 ? summary.tags : ['政策', '湖北省'], // 确保有默认标签
          keyPoints: summary.keyPoints && summary.keyPoints.length > 0 ? summary.keyPoints : ['请查看原文了解详情'],
          requirements: summary.requirements || []
        };
        
        // 保存到数据库
        await savePolicyToDatabase(pool, fullPolicy);
        
        // 间隔一段时间再处理下一条，避免请求过于频繁
        await new Promise(resolve => setTimeout(resolve, 2000));
      } catch (error) {
        console.error(`处理政策失败: ${policyItem.title}`, error);
      }
    }
    
    console.log('政策抓取完成');
    pool.end();
  } catch (error) {
    console.error('程序执行失败:', error);
    process.exit(1);
  }
}

// 执行主函数
main(); 